﻿/* 
This file is part of Ingo Karstein's Long Path Support project

**Do not remove this comment**

Please see the project homepage at CodePlex:
  http://longpathsupport.codeplex.com/

Please see my blog:
  http://ikarstein.wordpress.com

This code is used in the project "RoboPowerCopy"
  http://robopowercopy.codeplex.com

Licence: GPLv2
    Ingo Karstein's SharePoint 2010 Custom Ribbon Demo
    Copyright (C) 2011  Ingo Karstein, ikarstein@hotmail.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;

internal class HardLinkHelper
{
    internal struct BY_HANDLE_FILE_INFORMATION
    {
        public uint FileAttributes;
        public LongPathSupport.FILETIME CreationTime;
        public LongPathSupport.FILETIME LastAccessTime;
        public LongPathSupport.FILETIME LastWriteTime;
        public uint VolumeSerialNumber;
        public uint FileSizeHigh;
        public uint FileSizeLow;
        public uint NumberOfLinks;
        public uint FileIndexHigh;
        public uint FileIndexLow;
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern bool GetFileInformationByHandle(SafeFileHandle hFile,
       out BY_HANDLE_FILE_INFORMATION lpFileInformation);

    static HardLinkHelper()
    {
        AppDomain.CurrentDomain.UnhandledException += new System.UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    }

    static void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
    {
        //MessageBox.Show(((Exception)e.ExceptionObject).Message);
    }

    public static BY_HANDLE_FILE_INFORMATION? GetFileInfo(System.IO.FileInfo fi)
    {
        System.IO.FileStream fs = null;

        BY_HANDLE_FILE_INFORMATION ret;
        try
        {
            fs = fi.Open(System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
            Microsoft.Win32.SafeHandles.SafeFileHandle sfh = fs.SafeFileHandle;
            if( !sfh.IsClosed && !sfh.IsInvalid )
            {
                GetFileInformationByHandle(sfh, out ret);
                return ret;
            }
            else
            {
                return null;
            }
        }
        catch
        {
            return null;
        }
        finally
        {
            if( fs != null )
            {
                fs.Close();
            };
        }
    }

    public static BY_HANDLE_FILE_INFORMATION? GetFileInfo(LongFileInfo fi)
    {
        System.IO.FileStream fs = null;
        BY_HANDLE_FILE_INFORMATION ret;
        try
        {
            fs = fi.Open(System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
            Microsoft.Win32.SafeHandles.SafeFileHandle sfh = fs.SafeFileHandle;
            if( !sfh.IsClosed && !sfh.IsInvalid )
            {
                GetFileInformationByHandle(sfh, out ret);
                return ret;
            }
            else
            {
                return null;
            }
        }
        catch
        {
            return null;
        }
        finally
        {
            if( fs != null )
                fs.Close();
        }
    }

    public static bool TypeAvailable()
    {
        return true;
    }
}
